/*
 * @Author       : 魏威 <1209562577@qq.com>
 * @Date         : 2021-09-26 19:53 周日
 * @Description  : 封装自己的http请求
 */

import { useAuthContext } from 'context/auth-context';
import qs from 'qs';
import * as auth from '../auth-provider';

/** api地址 */
const apiUrl = process.env.REACT_APP_API_URL;

interface Config extends RequestInit {
  token?: string;
  data?: object;
}

/** 通用请求方法
 * @param endPoint 请求地址
 * @param config 请求常用配置
 * @returns 请求的数据
 */
export const http = async (
  endPoint: string,
  { data, token, headers, ...customConfig }: Config = {}
) => {
  /** 默认配制 */
  const config = {
    method: 'GET',
    headers: {
      Authorization: token ? `Bearer ${token}` : '',
      'Content-Type': data ? 'application/json' : ''
    },
    ...customConfig
  };

  if (config.method.toUpperCase() === 'GET') {
    endPoint += `?${qs.stringify(data)}`;
  } else {
    config.body = JSON.stringify(data || {});
  }

  return window.fetch(`${apiUrl}/${endPoint}`, config).then(async (respone) => {
    if (respone.status === 401) {
      await auth.logout();
      window.location.reload();
      return Promise.reject({ message: '请重新登录' });
    }
    const data = await respone.json();
    if (respone.ok) {
      return data;
    } else {
      return Promise.reject(data);
    }
  });
};

export const useHttp = () => {
  const { user } = useAuthContext();
  return (...[endpoint, config]: Parameters<typeof http>) =>
    http(endpoint, { ...config, token: user?.token });
};

// // 联合类型
// type FavoriteNumber = string | number;

// let myFavoriteNumber: FavoriteNumber;
// myFavoriteNumber = 'seven';
// myFavoriteNumber = 7;

// // 不能将类型“{}”分配给类型“string | number”
// // myFavoriteNumber = {};

// let wakerFavoriteNumber: FavoriteNumber;

// // type 和 interface大部分情况下可以互换
// // 但interface不能使用联合类型和交叉类型

// type Person = {
//   name: string;
//   age: number;
// };

// // Utility Type

// const xiaoMing: Partial<Person> = {};
// const shenmiren: Omit<Person, 'age'> = { name: 'waker' };
// console.log(xiaoMing);
// console.log(shenmiren);
